package cn.orangelite.ai.controller;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.orangelite.ai.domain.AiGptKey;
import cn.orangelite.ai.domain.AiKnowledge;
import cn.orangelite.ai.service.IAiGptKeyService;
import cn.orangelite.ai.service.IAiKnowledgeService;
import cn.orangelite.common.core.utils.StringUtils;
import cn.orangelite.common.core.web.controller.BaseController;
import cn.orangelite.common.core.web.domain.AjaxResult;
import cn.orangelite.common.core.web.page.TableDataInfo;
import cn.orangelite.common.log.annotation.Log;
import cn.orangelite.common.log.enums.BusinessType;
import cn.orangelite.common.security.annotation.RequiresPermissions;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

@RestController
@RequestMapping("/knowledge")
public class AiKnowledgeBase extends BaseController {
    @Autowired
    private IAiKnowledgeService aiKnowledgeService;
    @Autowired
    private IAiGptKeyService aiGptKeyService;

    @Value("${langchain.domain}")
    private String langchainDomain;

    @RequiresPermissions("ai:knowledge:list")
    @GetMapping("/list")
    public TableDataInfo list(AiKnowledge aiKnowledge)
    {
        startPage();
        List<AiKnowledge> list = aiKnowledgeService.list(Wrappers.<AiKnowledge>lambdaQuery().like(StringUtils.isNotEmpty(aiKnowledge.getName()),AiKnowledge::getName,aiKnowledge.getName()).orderByDesc(AiKnowledge::getId));
        return getDataTable(list);
    }

    @RequiresPermissions("ai:knowledge:query")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return success(aiKnowledgeService.getById(id));
    }

    /**
     * 新增gptkey

     */
    @RequiresPermissions("ai:knowledge:add")
    @Log(title = "knowledge", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody AiKnowledge aiKnowledge) throws Exception {
        AiGptKey aiGptKey = new AiGptKey();
        aiGptKey.setState(0L);
        aiGptKey.setType(1);
        List<AiGptKey> aiGptKeys = aiGptKeyService.selectAiGptKeyList(aiGptKey);
        if(aiGptKeys.isEmpty()){
            throw new Exception("未设置或开启大预言模型");
        }

        AiGptKey aiGptKey2 = new AiGptKey();
        aiGptKey2.setState(0L);
        aiGptKey2.setType(2);
        List<AiGptKey> aiGptKeys2 = aiGptKeyService.selectAiGptKeyList(aiGptKey2);
        if(aiGptKeys2.isEmpty()){
            throw new Exception("未设置或开启向量化模型");
        }

        HashMap<String, Object> paramMap = new HashMap<>();
        paramMap.put("file_name",aiKnowledge.getFile());
        paramMap.put("openai_api_key",aiGptKeys.get(0).getKey());
        paramMap.put("model",aiGptKeys.get(0).getModel());
        paramMap.put("embeddings",aiGptKeys2.get(0).getModel());

        System.out.println(paramMap);

        JSONObject response;
        try{
            String post = HttpUtil.post(langchainDomain+"/gpt/knowledge_base_upload/add", JSONUtil.toJsonStr(paramMap));
            response = JSONUtil.parseObj(post);
        }catch (Exception e){
            throw new Exception("请求向量化错误");
        }
        if(!response.containsKey("code")){
            throw new Exception((String) response.get("detail"));
        }
        if((int)response.get("code")!=200){
            throw new Exception((String) response.get("message"));
        }

        return toAjax(aiKnowledgeService.save(aiKnowledge));
    }

    /**
     * 修改gptkey

     */
    @RequiresPermissions("ai:knowledge:edit")
    @Log(title = "knowledge", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody AiKnowledge aiKnowledge) throws Exception {
        AiGptKey aiGptKey = new AiGptKey();
        aiGptKey.setState(0L);
        aiGptKey.setType(1);
        List<AiGptKey> aiGptKeys = aiGptKeyService.selectAiGptKeyList(aiGptKey);

        AiGptKey aiGptKey2 = new AiGptKey();
        aiGptKey2.setState(0L);
        aiGptKey2.setType(2);
        List<AiGptKey> aiGptKeys2 = aiGptKeyService.selectAiGptKeyList(aiGptKey2);

        HashMap<String, Object> paramMap = new HashMap<>();
        paramMap.put("file_name",aiKnowledge.getFile());
        paramMap.put("openai_api_key",aiGptKeys.get(0).getKey());
        paramMap.put("model",aiGptKeys.get(0).getModel());
        paramMap.put("embeddings",aiGptKeys2.get(0).getModel());

        System.out.println(paramMap);

        JSONObject response;
        JSONObject deleteResponse;
        try{
            //先删除原先的
            AiKnowledge old = aiKnowledgeService.getById(aiKnowledge.getId());
            HashMap<String, Object> deleteParamMap = new HashMap<>();
            deleteParamMap.put("file_name",old.getPath());
            deleteParamMap.put("openai_api_key",aiGptKeys.get(0).getKey());
            deleteParamMap.put("model",aiGptKeys.get(0).getModel());
            deleteParamMap.put("embeddings",aiGptKeys2.get(0).getModel());
            String deletePost = HttpUtil.post(langchainDomain+"/gpt/knowledge_base_upload/delete", JSONUtil.toJsonStr(deleteParamMap));
            deleteResponse = JSONUtil.parseObj(deletePost);

            //再新增新的
            String post = HttpUtil.post(langchainDomain+"/gpt/knowledge_base_upload/add", JSONUtil.toJsonStr(paramMap));
            response = JSONUtil.parseObj(post);
        }catch (Exception e){
            throw new Exception("请求向量化错误");
        }
        if(!deleteResponse.containsKey("code")){
            throw new Exception((String) deleteResponse.get("detail"));
        }
        if((int)deleteResponse.get("code")!=200){
            throw new Exception((String) deleteResponse.get("message"));
        }



        if(!response.containsKey("code")){
            throw new Exception((String) response.get("detail"));
        }
        if((int)response.get("code")!=200){
            throw new Exception((String) response.get("message"));
        }
        return toAjax(aiKnowledgeService.updateById(aiKnowledge));
    }

    /**
     * 删除gptkey

     */
    @RequiresPermissions("ai:knowledge:remove")
    @Log(title = "knowledge", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) throws Exception {
        AiGptKey aiGptKey = new AiGptKey();
        aiGptKey.setState(0L);
        aiGptKey.setType(1);
        List<AiGptKey> aiGptKeys = aiGptKeyService.selectAiGptKeyList(aiGptKey);

        AiGptKey aiGptKey2 = new AiGptKey();
        aiGptKey2.setState(0L);
        aiGptKey2.setType(2);
        List<AiGptKey> aiGptKeys2 = aiGptKeyService.selectAiGptKeyList(aiGptKey2);

        JSONObject deleteResponse;
        for(Long id : ids){
            try{
                AiKnowledge old = aiKnowledgeService.getById(id);
                HashMap<String, Object> deleteParamMap = new HashMap<>();
                deleteParamMap.put("file_name",old.getPath());
                deleteParamMap.put("openai_api_key",aiGptKeys.get(0).getKey());
                deleteParamMap.put("model",aiGptKeys.get(0).getModel());
                deleteParamMap.put("embeddings",aiGptKeys2.get(0).getModel());
                String deletePost = HttpUtil.post(langchainDomain+"/gpt/knowledge_base_upload/delete", JSONUtil.toJsonStr(deleteParamMap));
                deleteResponse = JSONUtil.parseObj(deletePost);
            }catch (Exception e){
                throw new Exception("请求向量化错误");
            }

            if(!deleteResponse.containsKey("code")){
                throw new Exception((String) deleteResponse.get("detail"));
            }
            if((int)deleteResponse.get("code")!=200){
                throw new Exception((String) deleteResponse.get("message"));
            }
        }

        return toAjax(aiKnowledgeService.removeBatchByIds(Arrays.asList(ids)));
    }


    @RequiresPermissions("ai:knowledge:check")
    @GetMapping("/checkKnowledge/{id}/{page}/{size}")
    public AjaxResult checkDetail(@PathVariable Integer id,@PathVariable Integer page,@PathVariable Integer size) throws Exception {
        AiGptKey aiGptKey = new AiGptKey();
        aiGptKey.setState(0L);
        aiGptKey.setType(1);
        List<AiGptKey> aiGptKeys = aiGptKeyService.selectAiGptKeyList(aiGptKey);
        if(aiGptKeys.isEmpty()){
            throw new Exception("未设置或开启大模型");
        }

        AiGptKey aiGptKey2 = new AiGptKey();
        aiGptKey2.setState(0L);
        aiGptKey2.setType(2);
        List<AiGptKey> aiGptKeys2 = aiGptKeyService.selectAiGptKeyList(aiGptKey2);
        if(aiGptKeys2.isEmpty()){
            throw new Exception("未设置或开启向量化模型");
        }

        AiKnowledge knowledgeBase = aiKnowledgeService.getById(id);

        HashMap<String, Object> paramMap = new HashMap<>();
        paramMap.put("file_name",knowledgeBase.getFile());
        paramMap.put("openai_api_key",aiGptKeys.get(0).getKey());
        paramMap.put("model",aiGptKeys.get(0).getModel());
        paramMap.put("embeddings",aiGptKeys2.get(0).getModel());
        paramMap.put("page",page);
        paramMap.put("size",size);
        JSONObject response;

        String post = HttpUtil.post(langchainDomain+"/gpt/get_knowledge_base", JSONUtil.toJsonStr(paramMap));
        response = JSONUtil.parseObj(post);
        if((int)response.get("code")!=200){
            throw new Exception((String) response.get("message"));
        }
        return success(response.get("data"));
    }

}
